﻿using System.Xml.Linq;
using DonNicky.Common.Xml;
using Microsoft.CSharp.RuntimeBinder;
using NUnit.Framework;

namespace TestCases
{
    [TestFixture]
    public class DynamicXmlElementTests
    {
        public static readonly XDocument SimpleXDocument =
            XDocument.Parse("<?xml version=\"1.0\" encoding=\"utf-8\" ?><file><header><title attr1=\"Main\">Welcome</title></header><message flag=\"None\"><body>Hello, World!</body><parameter>Param1</parameter><parameter>Param2</parameter><parameter>Param3</parameter></message></file>");

        public static readonly XDocument Vypiska = XDocument.Load(@"..\..\vypiska.xml");

        [Test]
        public void GetSingleElementValue()
        {
            dynamic xmlElement = new DynamicXmlElement(SimpleXDocument.Root);
            Assert.AreEqual("Welcome", (string)xmlElement.header.title);
            Assert.AreEqual("Hello, World!", (string)xmlElement.message.body);
        }

        [Test]
        public void GetArrayElementValueByIndex()
        {
            dynamic xmlElement = new DynamicXmlElement(SimpleXDocument.Root);
            Assert.AreEqual("Param1", (string)xmlElement.message.parameter[0]);
            Assert.AreEqual("Param2", (string)xmlElement.message.parameter[1]);
            Assert.AreEqual("Param3", (string)xmlElement.message.parameter[2]);
        }

        [Test]
        public void GetArrayElementValueByEnumeration()
        {
            dynamic xmlElement = new DynamicXmlElement(SimpleXDocument.Root);
            var paramIndex = 1;
            foreach (var parameter in xmlElement.message.parameter)
            {
                Assert.AreEqual(string.Format("Param{0}", paramIndex), (string)parameter);
                paramIndex++;
            }
        }

        [Test]
        public void GetLengthOfElementsArray()
        {
            dynamic xmlElement = new DynamicXmlElement(SimpleXDocument.Root);
            Assert.AreEqual(3, xmlElement.message.parameter.Count);
        }

        [Test]
        public void GetAttributeValueFromElementWithoutDescendants()
        {
            dynamic xmlElement = new DynamicXmlElement(SimpleXDocument.Root);
            Assert.AreEqual("Main", (string)xmlElement.header.title.attr1);
        }

        [Test]
        public void GetAttributeValueFromElementWithDescendants()
        {
            dynamic xmlElement = new DynamicXmlElement(SimpleXDocument.Root);
            Assert.AreEqual("None", (string)xmlElement.message.flag);

            xmlElement = new DynamicXmlElement(Vypiska.Root);
            Assert.AreEqual("ОписьЗапросовВыписок", (string)xmlElement.ПачкаИсходящихДокументов.ВходящийДокумент.Вариант);
        }

        [Test, Ignore("хз, что этот тест делает")]
        public void GetSingleElementWithNameOccuringInItsDescendants()
        {
            dynamic xmlElement = new DynamicXmlElement(Vypiska.Root);
            var ex = Assert.Throws<RuntimeBinderException>(() =>
                                                               {
#pragma warning disable 168
                                                                   var elementsCount =
                                                                       xmlElement.ПачкаИсходящихДокументов.
                                                                           ВходящийДокумент.Count;
#pragma warning restore 168
                                                               });
            Assert.True(ex.Message.Contains("System.Xml.Linq.XElement") && ex.Message.Contains("Count"));
        }

        [Test]
        public void CompareElementValueWithString()
        {
            dynamic xmlElement = new DynamicXmlElement(SimpleXDocument.Root);
            if (xmlElement.header.title == "Welcome") { }
            else
                Assert.Fail();
            if (xmlElement.header.title != "Welcome")
                Assert.Fail();
            if (xmlElement.header.title == "fcsjkw4jr")
                Assert.Fail();
        }

        [Test]
        public void CompareAttributeValueWithString()
        {
            dynamic xmlElement = new DynamicXmlElement(SimpleXDocument.Root);
            if (xmlElement.header.title.attr1 == "Main") { }
            else
                Assert.Fail();
            if (xmlElement.header.title.attr1 != "Main")
                Assert.Fail();
            if (xmlElement.header.title.attr1 == "mgbgbeth4")
                Assert.Fail();
        }

        [Test]
        public void TraditionalXElementAccess()
        {
            dynamic xmlElement = new DynamicXmlElement(SimpleXDocument.Root);
            var xElement = ((XElement)xmlElement.message).Element("body");
            if (xElement != null)
                Assert.AreEqual("Hello, World!", xElement.Value);
            else
                Assert.Fail();
        }
    }
}
